package com.msb.juc.thread.basic;

import java.text.DecimalFormat;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * 设置多少个线程合适
 * @author HuanyuLee
 * @date 2022/3/12
 */
public class T01_AddNumber {
    private static final double[] nums = new double[100000000];
    private static final Random r = new Random();
    private static final DecimalFormat df = new DecimalFormat("0.00");
    static {
        for (int i = 0; i < nums.length; i++) {
            nums[i] = r.nextDouble();
        }
    }
    /**
     * 单线程计算
     */
    private static void m1(){
        long start = System.currentTimeMillis();
        double result = 0.0;
        for (double num : nums) {
            result += num;
        }
        long end = System.currentTimeMillis();
        System.out.println("m1: " + (end-start) + " result = " + df.format(result));
    }

    /**
     * 两个线程计算
     */
    static double result = 0.0, result1 = 0.0, result2 = 0.0;
    private static void m2() throws Exception {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < nums.length / 2; i++) {
                result1 += nums[i];
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = nums.length / 2; i < nums.length; i++) {
                result2 += nums[i];
            }
        });
        long start = System.currentTimeMillis();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        result = result1 + result2;
        long end = System.currentTimeMillis();
        System.out.println("m2: " + (end-start) + " result = " + df.format(result));
    }

    /**
     * 多线程计算
     */
    private static void m3() throws Exception{
        int threadCount = 5;
        Thread[] threads = new Thread[threadCount];
        double[] results = new double[threadCount];
        int segmentCount = nums.length / threadCount;
        CountDownLatch latch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            int m = i;
            threads[i] = new Thread(() -> {
                if (m == threadCount - 1) {
                    for (int j = segmentCount * m; j < nums.length; j++)
                        results[m] += nums[j];
                } else {
                    for (int j = segmentCount * m; j < (m + 1) * segmentCount; j++)
                        results[m] += nums[j];
                }
                latch.countDown();
            });
        }

        double result = 0.0;
        long start = System.currentTimeMillis();
        for (Thread thread : threads){
            thread.start();
        }

        latch.await();
        for (double v : results) {
            result += v;
        }

        long end = System.currentTimeMillis();
        System.out.println("m3: " + (end-start) + " result = " + df.format(result));
    }

    public static void main(String[] args) throws Exception {
        m1();
        m2();
        m3();
    }
}
